﻿using System.Linq;
using Super_Management_Mayhem.Screens.Menu.CreateAvatarColor;
using Super_Management_Mayhem.Screens.Playing.Players;
using Transformable_Engine_v2.Engine.Animation.PositionAnimation;
using Transformable_Engine_v2.Engine.Animation.Trajectory;
using Transformable_Engine_v2.Engine.GameObjects.Containers;
using Transformable_Engine_v2.Engine.Helper;
using Transformable_Engine_v2.Engine.Transformable_Math.Geometry;

namespace Super_Management_Mayhem.Screens.Menu.SelectTeams
{
    public class SelectTeamsMenu : BaseMenuScreen<MainMenu.Menu>
    {
        public static bool HasTeams
        {
            get
            {
                return _instance != null;
            }
        }

        public new static void Die()
        {
            if(HasTeams)
            {
                ((Container) _instance).Die();
                _instance = null;
            }
                
        }

        public Team[] Teams { get; private set; }

        private static SelectTeamsMenu _instance;

        private readonly Container[] _buttons;
        private readonly PlayerIcon[] _cursorContainer;
        private int[] _cursorIndex;

        private readonly Container _buttonContainer;

        private int _playerCount;

        private SelectTeamsMenu(TE_Vector2 size,
                                int playerCount,
                                Team[] teams)
        {
            Teams = teams;

            _playerCount = playerCount;
            AddChildren(Title.Blue("Select a team", size));

            _buttonContainer = new Container(size.X / 2, (size.Y - 4) / 2);

            _buttons = new Container[teams.Length];
            _cursorContainer = new PlayerIcon[playerCount];
            _cursorIndex = new int[playerCount];

            for (int i = 0; i < teams.Length; i++)
            {
                _buttons[i] = new TeamButton(teams[i]) { PositionGridBound = new TE_Vector2(0, ((i * 2 + 1) / (teams.Length + 1.0f) - 0.5f) * (size.Y - 3 - _buttonContainer.PositionGridBound.Y)) };
                _buttonContainer.AddChildren(_buttons[i]);
            }

            AddChildren(_buttonContainer);
        }

        public void PlayerSelect(int id)
        {
            LeavePlayer(id);
            EnterPlayer(id, false);
        }

        public void EnterPlayer(int id, bool active)
        {
            if(_cursorContainer[id - 1] != null)
                _cursorContainer[id - 1].Die();

            if(active)
                _cursorIndex[id - 1] = 0;

            _cursorContainer[id - 1] = new PlayerIcon(Teams[_cursorIndex[id - 1]].GetColor(), active) { PositionGridBound = new TE_Vector2((id - (_playerCount + 1.0f) / 2) / (_playerCount + 1) * 16, _buttons[_cursorIndex[id - 1]].PositionGridBound.Y - 1)};
            _buttonContainer.AddChildren(_cursorContainer[id - 1]);
        }

        public void LeavePlayer(int id)
        {
            _cursorContainer[id - 1].Die();
            _cursorContainer[id - 1] = null;
        }

        void MoveUp(int id)
        {
            if(_cursorIndex[id - 1] > 0)
            {
                _cursorIndex[id - 1]--;

                Move(id);
            }
        }

        void MoveDown(int id)
        {
            if(_cursorIndex[id - 1] < _buttons.Length - 1)
            {
                _cursorIndex[id - 1]++;

                Move(id);
            }
        }

        void Move(int id)
        {
            _cursorContainer[id - 1].ClearAnimation();
            _cursorContainer[id - 1].AddAnimations(new PositionAnimation(new LinearEasing(), 
                                    new TE_Vector2(_cursorContainer[id - 1].PositionGridBound.X, 
                                                   _buttons[_cursorIndex[id - 1]].PositionGridBound.Y - 1), 
                                    250, false, 0));

            _cursorContainer[id - 1].ChangeColor(Teams[_cursorIndex[id - 1]].GetColor(), 250);
        }

        public override void AcceptKey(int id)
        {
            PlayerSelect(id);
            ChangeScreen(id, MainMenu.Menu.Waiting);
        }
        public override void CancelKey(int id)
        {
            ChangeScreen(id, MainMenu.Menu.SelectAvatar);
            LeavePlayer(id);
        }
        public override void DownKey(int id)
        {
            MoveDown(id);
        }
        public override void LeftKey(int id)
        {
            MoveUp(id);
        }
        public override void RightKey(int id)
        {
            MoveDown(id);
        }
        public override void UpKey(int id)
        {
            MoveUp(id);
        }

        public static SelectTeamsMenu CreateInstance(TE_Vector2 size,
                                                     int teamCount,
                                                     int playerCount,
                                                     int id)
        {
            if (_instance == null)
            {
                _instance = new SelectTeamsMenu(size, playerCount, CreateTeams(teamCount));
            }
            _instance.EnterPlayer(id, true);
            return _instance;
        }

        public static SelectTeamsMenu GetInstance()
        {
            return _instance;
        }

        private static Team[] CreateTeams(int count)
        {
            return Enumerable.Range(0, AvatarColorMenu.AvailableColors.Length - 1)
                .OrderBy(c => Randomizer.Double())
                .Take(count)
                .Select(c => new Team(c))
                .ToArray();
        }

        public override void FixedStepUpdate(System.TimeSpan gameTime)
        {
            //Do nothing
        }

        public void RealFixedStepUpdate(System.TimeSpan gameTime)
        {
            base.FixedStepUpdate(gameTime);
        }

        public static void SingleFixedStepUpdate(System.TimeSpan gameTime)
        {
            //Quick fix to have the menu instance only updated once
            if(_instance != null)
                _instance.RealFixedStepUpdate(gameTime);
        }

        public Team GetTeam(int id)
        {
            return Teams[_cursorIndex[id - 1]];
        }
    }
}
